package com.witmore.neutron.ai.mcp.server.trading.service;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jk.common.response.ResponsePageResult;
import com.witmore.neutron.ai.mcp.server.trading.controller.dto.StockAlertConfigDTO;
import com.witmore.neutron.ai.mcp.server.trading.db.entity.ScorpionTradingUserDO;
import com.witmore.neutron.ai.mcp.server.trading.db.entity.ScorpionUserStockRelationDO;
import com.witmore.neutron.ai.mcp.server.trading.db.mapper.ScorpionTradingUserMapper;
import com.witmore.neutron.ai.mcp.server.trading.db.mapper.ScorpionUserStockRelationMapper;
import com.witmore.neutron.ai.mcp.server.trading.dto.AlertConfigDTO;
import com.witmore.neutron.ai.mcp.server.trading.scheduler.DynamicAlertTaskScheduler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 异动预警配置服务
 *
 * @author 豆子高
 * @since 2025-01-06
 */
@Slf4j
@Service
public class AlertConfigService {

    @Autowired
    private ScorpionTradingUserMapper scorpionTradingUserMapper;

    @Autowired
    private ScorpionUserStockRelationMapper scorpionUserStockRelationMapper;
    @Autowired
    private AkshareService akshareService;
    @Autowired
    private DynamicAlertTaskScheduler dynamicAlertTaskScheduler;

    /**
     * 保存或更新单个股票的异动预警配置
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveOrUpdateStockAlertConfig(AlertConfigDTO alertConfigDTO) {
        try {
            log.info("开始保存单个股票异动预警配置，配置信息：{}", JSON.toJSONString(alertConfigDTO));

            if (!StringUtils.hasText(alertConfigDTO.getStockCode())) {
                throw new RuntimeException("股票代码不能为空");
            }

            // 1. 查找或创建用户
            ScorpionTradingUserDO user = findOrCreateUser(alertConfigDTO.getPhone());

            // 2. 查找或创建股票关联关系
            ScorpionUserStockRelationDO stockRelation = findOrCreateStockRelation(user.getId(), alertConfigDTO.getStockCode());

            // 3. 更新该股票的预警配置
            updateStockAlertConfig(stockRelation.getId(), alertConfigDTO);

            log.info("单个股票异动预警配置保存成功，用户ID：{}，股票代码：{}", user.getId(), alertConfigDTO.getStockCode());
            return true;

        } catch (Exception e) {
            log.error("保存单个股票异动预警配置失败", e);
            return false;
        }
    }

    /**
     * 批量保存或更新异动预警配置（兼容原有逻辑）
     */
    @Transactional(rollbackFor = Exception.class)
    public String saveOrUpdateAlertConfig(AlertConfigDTO alertConfigDTO) {
        try {
            log.info("开始保存批量异动预警配置，配置信息：{}", JSON.toJSONString(alertConfigDTO));

            // 1. 查找或创建用户
            ScorpionTradingUserDO user = findOrCreateUser(alertConfigDTO.getPhone());

            // 2. 批量更新用户股票关联关系和预警配置
            batchUpdateUserStockRelations(user.getId(), alertConfigDTO);

            log.info("批量异动预警配置保存成功，用户ID：{}", user.getId());
            return "异动预警配置保存成功";

        } catch (Exception e) {
            log.error("保存批量异动预警配置失败", e);
            throw new RuntimeException("保存异动预警配置失败：" + e.getMessage());
        }
    }

    /**
     * 查找或创建用户
     */
    public ScorpionTradingUserDO findOrCreateUser(String userPhone) {
        // 使用默认手机号如果没有提供

        LambdaQueryWrapper<ScorpionTradingUserDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ScorpionTradingUserDO::getPhone, userPhone)
                .eq(ScorpionTradingUserDO::getIsDeleted, 0);

        ScorpionTradingUserDO user = scorpionTradingUserMapper.selectOne(queryWrapper);

        if (user == null) {
            // 创建新用户
            user = new ScorpionTradingUserDO();
            user.setUserName(userPhone);
            user.setPhone(userPhone);
            user.setCreateTime(LocalDateTime.now());
            user.setUpdateTime(LocalDateTime.now());
            user.setIsDeleted((byte) 0);

            scorpionTradingUserMapper.insert(user);
            log.info("创建新用户成功，用户ID：{}，手机号：{}", user.getId(), userPhone);
        }

        return user;
    }

    /**
     * 查找或创建股票关联关系
     */
    private ScorpionUserStockRelationDO findOrCreateStockRelation(Long userId, String stockCode) throws Exception {
        LambdaQueryWrapper<ScorpionUserStockRelationDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ScorpionUserStockRelationDO::getUserId, userId)
                .eq(ScorpionUserStockRelationDO::getStockCode, stockCode)
                .eq(ScorpionUserStockRelationDO::getIsDeleted, 0);

        ScorpionUserStockRelationDO stockRelation = scorpionUserStockRelationMapper.selectOne(queryWrapper);

        if (stockRelation == null) {
            // 创建新的股票关联关系
            stockRelation = new ScorpionUserStockRelationDO();
            stockRelation.setUserId(userId);
            stockRelation.setStockCode(stockCode);
            stockRelation.setStockName(this.getStockName(stockCode));
            stockRelation.setAlertPushEnabled(1); // 默认开启预警推送
            stockRelation.setCreateTime(LocalDateTime.now());
            stockRelation.setUpdateTime(LocalDateTime.now());
            stockRelation.setIsDeleted((byte) 0);
            scorpionUserStockRelationMapper.insert(stockRelation);
            log.info("创建用户股票关联关系，用户ID：{}，股票代码：{}，默认开启预警推送", userId, stockCode);
        }

        return stockRelation;
    }


    public String getStockName(String stockCode) throws Exception {
        try {
            String stockIndividualInfoEm = akshareService.stockIndividualInfoEm(stockCode);
            ObjectMapper mapper = new ObjectMapper();
            JsonNode array = mapper.readTree(stockIndividualInfoEm);

            String stockName = null;
            for (JsonNode node : array) {
                if ("股票简称".equals(node.get("item").asText())) {
                    stockName = node.get("value").asText();
                    break;
                }
            }
            return stockName;
        } catch (Exception e) {
            log.error("获取股票名称失败", e);
            throw new Exception("股票名称或代码异常，请稍后重试！",e);
        }
    }

    /**
     * 更新单个股票的预警配置
     */
    private void updateStockAlertConfig(Long relationId, AlertConfigDTO alertConfigDTO) {
        // 构建配置JSON
        AlertConfigJSON configJson = new AlertConfigJSON();
        configJson.setRiseRatio(alertConfigDTO.getRiseRatio());
        configJson.setFallRatio(alertConfigDTO.getFallRatio());
        configJson.setPushFrequency(alertConfigDTO.getPushFrequency());

        String alertConfigJsonStr = JSON.toJSONString(configJson);

        // 更新股票关联关系的预警配置
        LambdaUpdateWrapper<ScorpionUserStockRelationDO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(ScorpionUserStockRelationDO::getId, relationId)
                .set(ScorpionUserStockRelationDO::getAlertConfig, alertConfigJsonStr)
                .set(ScorpionUserStockRelationDO::getUpdateTime, LocalDateTime.now())
                .set(alertConfigDTO.getAlertEnabled() != null, ScorpionUserStockRelationDO::getAlertPushEnabled, alertConfigDTO.getAlertEnabled());

        scorpionUserStockRelationMapper.update(null, updateWrapper);
        log.info("股票预警配置更新成功，关联关系ID：{}，配置：{}", relationId, alertConfigJsonStr);

        // 更新定时任务
        try {
            ScorpionUserStockRelationDO updatedRelation = scorpionUserStockRelationMapper.selectById(relationId);
            if (updatedRelation != null) {
                dynamicAlertTaskScheduler.updateAlertTask(updatedRelation);
                log.info("定时任务更新成功，关联关系ID：{}", relationId);
            }
        } catch (Exception e) {
            log.warn("更新定时任务失败，关联关系ID：{}", relationId, e);
        }
    }

    /**
     * 批量更新用户股票关联关系和预警配置
     */
    private void batchUpdateUserStockRelations(Long userId, AlertConfigDTO alertConfigDTO) throws Exception {
        if (!StringUtils.hasText(alertConfigDTO.getStockCodes())) {
            log.warn("股票代码为空，跳过股票关联关系更新");
            return;
        }

        // 解析股票代码
        List<String> stockCodeList = Arrays.stream(alertConfigDTO.getStockCodes().split(","))
                .map(String::trim)
                .filter(StringUtils::hasText)
                .toList();

        for (String stockCode : stockCodeList) {
            // 查找或创建股票关联关系
            ScorpionUserStockRelationDO stockRelation = findOrCreateStockRelation(userId, stockCode);

            // 构建单个股票的配置DTO
            AlertConfigDTO stockAlertConfig = new AlertConfigDTO();
            stockAlertConfig.setStockCode(stockCode);
            stockAlertConfig.setRiseRatio(alertConfigDTO.getRiseRatio());
            stockAlertConfig.setFallRatio(alertConfigDTO.getFallRatio());
            stockAlertConfig.setPushFrequency(alertConfigDTO.getPushFrequency());
            stockAlertConfig.setAlertEnabled(alertConfigDTO.getAlertEnabled());

            // 更新该股票的预警配置
            updateStockAlertConfig(stockRelation.getId(), stockAlertConfig);
        }
    }

    /**
     * 获取用户的异动预警配置（兼容原有逻辑，返回第一个股票的配置）
     */
    public AlertConfigDTO getUserAlertConfig(String userPhone) {

        // 查找用户
        LambdaQueryWrapper<ScorpionTradingUserDO> userQuery = new LambdaQueryWrapper<>();
        userQuery.eq(ScorpionTradingUserDO::getPhone, userPhone)
                .eq(ScorpionTradingUserDO::getIsDeleted, 0);

        ScorpionTradingUserDO user = scorpionTradingUserMapper.selectOne(userQuery);
        if (user == null) {
            return null;
        }

        // 查找用户的股票关联关系
        LambdaQueryWrapper<ScorpionUserStockRelationDO> stockQuery = new LambdaQueryWrapper<>();
        stockQuery.eq(ScorpionUserStockRelationDO::getUserId, user.getId())
                .eq(ScorpionUserStockRelationDO::getIsDeleted, 0)
                .orderByAsc(ScorpionUserStockRelationDO::getCreateTime);

        List<ScorpionUserStockRelationDO> stockRelations = scorpionUserStockRelationMapper.selectList(stockQuery);
        if (stockRelations.isEmpty()) {
            return null;
        }

        // 组合所有股票代码
        String stockCodes = stockRelations.stream()
                .map(ScorpionUserStockRelationDO::getStockCode)
                .collect(Collectors.joining(","));

        // 取第一个有配置的股票作为示例配置
        for (ScorpionUserStockRelationDO stockRelation : stockRelations) {
            if (StringUtils.hasText(stockRelation.getAlertConfig())) {
                try {
                    AlertConfigJSON configJson = JSON.parseObject(stockRelation.getAlertConfig(), AlertConfigJSON.class);

                    AlertConfigDTO alertConfigDTO = new AlertConfigDTO();
                    alertConfigDTO.setStockCodes(stockCodes);
                    alertConfigDTO.setRiseRatio(configJson.getRiseRatio());
                    alertConfigDTO.setFallRatio(configJson.getFallRatio());
                    alertConfigDTO.setPushFrequency(configJson.getPushFrequency());
                    alertConfigDTO.setPhone(userPhone);
                    alertConfigDTO.setAlertEnabled(stockRelation.getAlertPushEnabled());

                    return alertConfigDTO;
                } catch (Exception e) {
                    log.error("解析股票异动预警配置失败，关联关系ID：{}", stockRelation.getId(), e);
                }
            }
        }

        return null;
    }

    /**
     * 根据股票代码获取用户的异动预警配置
     */
    public List<AlertConfigDTO> getStockAlertConfigsByStockCodes(String userPhone, String stockCodes) {
        if (!StringUtils.hasText(stockCodes)) {
            return getAllUserStockAlertConfigs(userPhone);
        }

        // 查找用户
        LambdaQueryWrapper<ScorpionTradingUserDO> userQuery = new LambdaQueryWrapper<>();
        userQuery.eq(ScorpionTradingUserDO::getPhone, userPhone)
                .eq(ScorpionTradingUserDO::getIsDeleted, 0);

        ScorpionTradingUserDO user = scorpionTradingUserMapper.selectOne(userQuery);
        if (user == null) {
            return null;
        }

        // 解析股票代码
        List<String> stockCodeList = Arrays.stream(stockCodes.split(","))
                .map(String::trim)
                .filter(StringUtils::hasText)
                .toList();

        if (stockCodeList.isEmpty()) {
            return null;
        }

        // 查找指定股票的关联关系
        LambdaQueryWrapper<ScorpionUserStockRelationDO> stockQuery = new LambdaQueryWrapper<>();
        stockQuery.eq(ScorpionUserStockRelationDO::getUserId, user.getId())
                .in(ScorpionUserStockRelationDO::getStockCode, stockCodeList)
                .eq(ScorpionUserStockRelationDO::getIsDeleted, 0)
                .orderByAsc(ScorpionUserStockRelationDO::getCreateTime);

        List<ScorpionUserStockRelationDO> stockRelations = scorpionUserStockRelationMapper.selectList(stockQuery);

        return stockRelations.stream()
                .filter(relation -> StringUtils.hasText(relation.getAlertConfig()))
                .map(relation -> {
                    try {
                        AlertConfigJSON configJson = JSON.parseObject(relation.getAlertConfig(), AlertConfigJSON.class);

                        AlertConfigDTO alertConfigDTO = new AlertConfigDTO();
                        alertConfigDTO.setStockCode(relation.getStockCode());
                        alertConfigDTO.setRiseRatio(configJson.getRiseRatio());
                        alertConfigDTO.setFallRatio(configJson.getFallRatio());
                        alertConfigDTO.setPushFrequency(configJson.getPushFrequency());
                        alertConfigDTO.setPhone(userPhone);
                        alertConfigDTO.setStockName(relation.getStockName());

                        return alertConfigDTO;
                    } catch (Exception e) {
                        log.error("解析股票异动预警配置失败，关联关系ID：{}", relation.getId(), e);
                        return null;
                    }
                })
                .filter(config -> config != null)
                .collect(Collectors.toList());
    }

    /**
     * 获取用户所有股票的异动预警配置
     */
    public List<AlertConfigDTO> getAllUserStockAlertConfigs(String userPhone) {

        // 查找用户
        LambdaQueryWrapper<ScorpionTradingUserDO> userQuery = new LambdaQueryWrapper<>();
        userQuery.eq(ScorpionTradingUserDO::getPhone, userPhone)
                .eq(ScorpionTradingUserDO::getIsDeleted, 0);

        ScorpionTradingUserDO user = scorpionTradingUserMapper.selectOne(userQuery);
        if (user == null) {
            return null;
        }

        // 查找用户的股票关联关系
        LambdaQueryWrapper<ScorpionUserStockRelationDO> stockQuery = new LambdaQueryWrapper<>();
        stockQuery.eq(ScorpionUserStockRelationDO::getUserId, user.getId())
                .eq(ScorpionUserStockRelationDO::getIsDeleted, 0)
                .orderByAsc(ScorpionUserStockRelationDO::getCreateTime);

        List<ScorpionUserStockRelationDO> stockRelations = scorpionUserStockRelationMapper.selectList(stockQuery);

        return stockRelations.stream()
                .filter(relation -> StringUtils.hasText(relation.getAlertConfig()))
                .map(relation -> {
                    try {
                        AlertConfigJSON configJson = JSON.parseObject(relation.getAlertConfig(), AlertConfigJSON.class);

                        AlertConfigDTO alertConfigDTO = new AlertConfigDTO();
                        alertConfigDTO.setStockCode(relation.getStockCode());
                        alertConfigDTO.setRiseRatio(configJson.getRiseRatio());
                        alertConfigDTO.setFallRatio(configJson.getFallRatio());
                        alertConfigDTO.setPushFrequency(configJson.getPushFrequency());
                        alertConfigDTO.setPhone(userPhone);
                        alertConfigDTO.setStockName(relation.getStockName());

                        return alertConfigDTO;
                    } catch (Exception e) {
                        log.error("解析股票异动预警配置失败，关联关系ID：{}", relation.getId(), e);
                        return null;
                    }
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }

    /**
     * 删除用户某个股票的异动预警配置
     */
    @Transactional(rollbackFor = Exception.class)
    public String deleteStockAlertConfig(String userPhone, String stockCode) {

        // 查找用户
        LambdaQueryWrapper<ScorpionTradingUserDO> userQuery = new LambdaQueryWrapper<>();
        userQuery.eq(ScorpionTradingUserDO::getPhone, userPhone)
                .eq(ScorpionTradingUserDO::getIsDeleted, 0);

        ScorpionTradingUserDO user = scorpionTradingUserMapper.selectOne(userQuery);
        if (user == null) {
            return "用户不存在";
        }

        // 查找股票关联关系
        ScorpionUserStockRelationDO stockRelation = scorpionUserStockRelationMapper.selectOne(new LambdaQueryWrapper<ScorpionUserStockRelationDO>()
                .eq(ScorpionUserStockRelationDO::getUserId, user.getId())
                .eq(ScorpionUserStockRelationDO::getStockCode, stockCode)
                .eq(ScorpionUserStockRelationDO::getIsDeleted, 0));
        if (stockRelation == null) {
            return "未找到该股票的配置";
        }

        // 清空预警配置
        scorpionUserStockRelationMapper.deleteById(stockRelation.getId());

        log.info("删除股票异动预警配置成功，用户ID：{}，股票代码：{}", user.getId(), stockCode);
        return "股票异动预警配置删除成功";
    }

    /**
     * 更新股票预警推送状态
     */
    @Transactional(rollbackFor = Exception.class)
    public String updateAlertPushStatus(String userPhone, String stockCodes, boolean enabled) {
        try {
            log.info("开始更新预警推送状态，手机号：{}，股票代码：{}，启用状态：{}", userPhone, stockCodes, enabled);

            // 1. 查找用户
            LambdaQueryWrapper<ScorpionTradingUserDO> userQuery = new LambdaQueryWrapper<>();
            userQuery.eq(ScorpionTradingUserDO::getPhone, userPhone)
                    .eq(ScorpionTradingUserDO::getIsDeleted, 0);
            ScorpionTradingUserDO user = scorpionTradingUserMapper.selectOne(userQuery);
            if (user == null) {
                return "用户不存在";
            }

            // 2. 处理股票代码
            int updatedCount = 0;
            List<String> stockCodeList;

            if (!StringUtils.hasText(stockCodes)) {
                // 如果不传股票代码，则更新该用户的所有股票
                LambdaQueryWrapper<ScorpionUserStockRelationDO> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(ScorpionUserStockRelationDO::getUserId, user.getId())
                        .eq(ScorpionUserStockRelationDO::getIsDeleted, 0);

                List<ScorpionUserStockRelationDO> allStockRelations = scorpionUserStockRelationMapper.selectList(queryWrapper);

                if (allStockRelations.isEmpty()) {
                    return "该用户暂无股票配置，无需设置推送状态";
                }

                // 批量更新所有股票的推送状态
                LambdaUpdateWrapper<ScorpionUserStockRelationDO> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(ScorpionUserStockRelationDO::getUserId, user.getId())
                        .eq(ScorpionUserStockRelationDO::getIsDeleted, 0)
                        .set(ScorpionUserStockRelationDO::getAlertPushEnabled, enabled ? 1 : 0)
                        .set(ScorpionUserStockRelationDO::getUpdateTime, LocalDateTime.now());

                updatedCount = scorpionUserStockRelationMapper.update(null, updateWrapper);
            } else {
                // 解析指定的股票代码
                stockCodeList = Arrays.stream(stockCodes.split(","))
                        .map(String::trim)
                        .filter(StringUtils::hasText)
                        .toList();

                if (stockCodeList.isEmpty()) {
                    return "股票代码格式错误";
                }

                // 3. 更新指定股票的预警推送状态
                for (String stockCode : stockCodeList) {
                    LambdaUpdateWrapper<ScorpionUserStockRelationDO> updateWrapper = new LambdaUpdateWrapper<>();
                    updateWrapper.eq(ScorpionUserStockRelationDO::getUserId, user.getId())
                            .eq(ScorpionUserStockRelationDO::getStockCode, stockCode)
                            .eq(ScorpionUserStockRelationDO::getIsDeleted, 0)
                            .set(ScorpionUserStockRelationDO::getAlertPushEnabled, enabled ? 1 : 0)
                            .set(ScorpionUserStockRelationDO::getUpdateTime, LocalDateTime.now());

                    int count = scorpionUserStockRelationMapper.update(null, updateWrapper);
                    updatedCount += count;
                }
            }

            String statusText = enabled ? "开启" : "关闭";
            String scopeText = !StringUtils.hasText(stockCodes) ? "全部" : "指定";
            log.info("更新预警推送状态成功，用户ID：{}，更新数量：{}，状态：{}，范围：{}", user.getId(), updatedCount, statusText, scopeText);

            if (updatedCount == 0) {
                return "未找到相关股票配置，请先创建预警配置";
            }

            String targetStocksText = !StringUtils.hasText(stockCodes) ?
                    String.format("全部 %d 支股票", updatedCount) :
                    String.format("%d 支指定股票", updatedCount);

            // 更新定时任务
            try {
                dynamicAlertTaskScheduler.updateUserAlertTasks(user.getId());
                log.info("批量更新用户定时任务成功，用户ID：{}", user.getId());
            } catch (Exception e) {
                log.warn("批量更新用户定时任务失败，用户ID：{}", user.getId(), e);
            }

            return String.format("已成功%s %s 的预警推送功能", statusText, targetStocksText);

        } catch (Exception e) {
            log.error("更新预警推送状态失败", e);
            throw new RuntimeException("更新预警推送状态失败：" + e.getMessage());
        }
    }

    /**
     * 查询股票预警推送状态
     */
    public String getAlertPushStatus(String userPhone, String stockCodes) {
        try {
            log.info("开始查询预警推送状态，手机号：{}，股票代码：{}", userPhone, stockCodes);

            // 1. 查找用户
            LambdaQueryWrapper<ScorpionTradingUserDO> userQuery = new LambdaQueryWrapper<>();
            userQuery.eq(ScorpionTradingUserDO::getPhone, userPhone)
                    .eq(ScorpionTradingUserDO::getIsDeleted, 0);
            ScorpionTradingUserDO user = scorpionTradingUserMapper.selectOne(userQuery);
            if (user == null) {
                return "用户不存在";
            }

            // 2. 查询股票关联关系
            LambdaQueryWrapper<ScorpionUserStockRelationDO> stockQuery = new LambdaQueryWrapper<>();
            stockQuery.eq(ScorpionUserStockRelationDO::getUserId, user.getId())
                    .eq(ScorpionUserStockRelationDO::getIsDeleted, 0);

            if (StringUtils.hasText(stockCodes)) {
                List<String> stockCodeList = Arrays.stream(stockCodes.split(","))
                        .map(String::trim)
                        .filter(StringUtils::hasText)
                        .collect(Collectors.toList());
                stockQuery.in(ScorpionUserStockRelationDO::getStockCode, stockCodeList);
            }

            List<ScorpionUserStockRelationDO> stockRelations = scorpionUserStockRelationMapper.selectList(stockQuery);

            if (stockRelations.isEmpty()) {
                return "未找到相关股票配置";
            }

            // 3. 构建返回结果
            StringBuilder result = new StringBuilder();
            result.append("📊 股票预警推送状态：\n\n");

            int enabledCount = 0;
            int disabledCount = 0;

            for (ScorpionUserStockRelationDO relation : stockRelations) {
                boolean isEnabled = relation.getAlertPushEnabled() != null && relation.getAlertPushEnabled() == 1;
                String status = isEnabled ? "✅ 已开启" : "❌ 已关闭";
                result.append(String.format("• %s (%s): %s\n",
                        relation.getStockCode(),
                        relation.getStockName(),
                        status));

                if (isEnabled) {
                    enabledCount++;
                } else {
                    disabledCount++;
                }
            }

            result.append("\n📈 统计信息：\n");
            result.append(String.format("• 总计：%d 支股票\n", stockRelations.size()));
            result.append(String.format("• 已开启：%d 支股票\n", enabledCount));
            result.append(String.format("• 已关闭：%d 支股票\n", disabledCount));

            return result.toString();

        } catch (Exception e) {
            log.error("查询预警推送状态失败", e);
            throw new RuntimeException("查询预警推送状态失败：" + e.getMessage());
        }
    }

    /**
     * 根据用户ID获取手机号
     *
     * @param userId 用户ID
     * @return 手机号，用户不存在时返回null
     */
    public String getUserPhoneById(Long userId) {
        try {
            LambdaQueryWrapper<ScorpionTradingUserDO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ScorpionTradingUserDO::getId, userId)
                    .eq(ScorpionTradingUserDO::getIsDeleted, 0);

            ScorpionTradingUserDO user = scorpionTradingUserMapper.selectOne(queryWrapper);
            if (user != null) {
                return user.getPhone();
            }

            log.warn("未找到用户信息: userId={}", userId);
            return null;

        } catch (Exception e) {
            log.error("根据用户ID获取手机号失败: userId={}", userId, e);
            return null;
        }
    }

    /**
     * 根据用户ID和配置ID获取股票预警配置
     *
     * @param userId   用户ID
     * @param configId 配置ID
     * @return 配置DTO，不存在时返回null
     */
    public StockAlertConfigDTO getStockAlertConfigById(Long userId, Long configId) {
        try {
            // 先验证用户
            String userPhone = getUserPhoneById(userId);
            if (userPhone == null) {
                log.warn("用户不存在: userId={}", userId);
                return null;
            }

            // 查找配置
            ScorpionUserStockRelationDO stockRelation = scorpionUserStockRelationMapper.selectById(configId);
            if (stockRelation == null || stockRelation.getIsDeleted() == 1) {
                log.warn("配置不存在或已删除: configId={}", configId);
                return null;
            }

            // 验证配置是否属于该用户
            if (!stockRelation.getUserId().equals(userId)) {
                log.warn("配置不属于该用户: configId={}, userId={}, actualUserId={}",
                        configId, userId, stockRelation.getUserId());
                return null;
            }

            // 转换为DTO
            return convertStockRelationToDTO(stockRelation, userPhone);

        } catch (Exception e) {
            log.error("根据ID获取股票预警配置失败: userId={}, configId={}", userId, configId, e);
            return null;
        }
    }

    /**
     * 分页查询用户的股票预警配置
     *
     * @param userId       用户ID
     * @param stockCode    股票代码（可选，模糊查询）
     * @param stockName    股票名称（可选，模糊查询）
     * @param alertEnabled 是否启用（可选）
     * @param page         页码
     * @param size         每页大小
     * @return 分页结果
     */
    public ResponsePageResult<StockAlertConfigDTO> queryStockAlertConfigs(Long userId, String stockCode, String stockName,
                                                                          Integer alertEnabled, long page, long size) {
        try {
            // 验证用户
            String userPhone = getUserPhoneById(userId);
            if (userPhone == null) {
                log.warn("用户不存在: userId={}", userId);
                // 创建空的Page对象并返回
                Page<StockAlertConfigDTO> emptyPage = new Page<>(page, size);
                emptyPage.setTotal(0);
                return ResponsePageResult.success(emptyPage);
            }

            // 分页查询
            Page<ScorpionUserStockRelationDO> resultPage =
                    scorpionUserStockRelationMapper.selectPage(new Page<>(page, size), new LambdaQueryWrapper<ScorpionUserStockRelationDO>()
                            .eq(ScorpionUserStockRelationDO::getUserId, userId)
                            .eq(ScorpionUserStockRelationDO::getIsDeleted, 0)
                            .like(StringUtils.hasText(stockCode), ScorpionUserStockRelationDO::getStockCode, stockCode)
                            .like(StringUtils.hasText(stockName), ScorpionUserStockRelationDO::getStockName, stockName)
                            .eq(alertEnabled != null, ScorpionUserStockRelationDO::getAlertPushEnabled, alertEnabled)
                            .orderByDesc(ScorpionUserStockRelationDO::getAlertPushEnabled)
                            .orderByDesc(ScorpionUserStockRelationDO::getUpdateTime)
                    );

            // 转换结果
            List<StockAlertConfigDTO> configs = resultPage.getRecords().stream()
                    .map(relation -> convertStockRelationToDTO(relation, userPhone))
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());

            // 创建Page对象并返回
            Page<StockAlertConfigDTO> configPage = new Page<>(page, size);
            configPage.setTotal(resultPage.getTotal());
            configPage.setRecords(configs);
            return ResponsePageResult.success(configPage);

        } catch (Exception e) {
            log.error("分页查询股票预警配置失败: userId={}", userId, e);
            // 创建空的Page对象并返回
            Page<StockAlertConfigDTO> emptyPage = new Page<>(page, size);
            emptyPage.setTotal(0);
            return ResponsePageResult.success(emptyPage);
        }
    }

    /**
     * 将股票关联关系转换为DTO
     */
    private StockAlertConfigDTO convertStockRelationToDTO(ScorpionUserStockRelationDO stockRelation, String userPhone) {
        try {
            if (stockRelation == null) {
                return null;
            }

            StockAlertConfigDTO dto = StockAlertConfigDTO.builder().build();
            BeanUtils.copyProperties(stockRelation, dto);
            dto.setId(stockRelation.getId());
            dto.setAlertEnabled(stockRelation.getAlertPushEnabled());
            dto.setPhone(userPhone);
            dto.setStockCode(stockRelation.getStockCode());

            // 解析配置JSON
            if (StringUtils.hasText(stockRelation.getAlertConfig())) {
                AlertConfigJSON configJson = JSON.parseObject(stockRelation.getAlertConfig(), AlertConfigJSON.class);
                if (configJson != null) {
                    dto.setRiseRatio(configJson.getRiseRatio());
                    dto.setFallRatio(configJson.getFallRatio());
                    dto.setPushFrequency(configJson.getPushFrequency());
                }
            }

            return dto;

        } catch (Exception e) {
            log.error("转换股票关联关系为DTO失败: relationId={}", stockRelation.getId(), e);
            return null;
        }
    }


    /**
     * 异动预警配置JSON内部类
     */
    @lombok.Data
    private static class AlertConfigJSON {
        private java.math.BigDecimal riseRatio;
        private java.math.BigDecimal fallRatio;
        private Integer pushFrequency;
    }
}
